<template>
  <div
    class="weekly-view"
    :style="{
      'background-image': `url(${backgroundImage})`
    }"
  >

    <div
      class="weekly-view__content"
    >
      <div class="header">
        <div class="header__left">
          <div class="header__left__time">
            <div class="time">
              {{ timeInfo?.time }}
            </div>
            <div
              class="date flex pointer"
              @click="handleOpenDatePicker"
            >
              <div>
                {{ getTimeInfo?.ymd }}
              </div>

              <div>
                {{ getTimeInfo?.day }}
              </div>

              <div style="margin-left: 10px;">
                <i class="el-icon-caret-bottom" />
              </div>

              <el-date-picker
                ref="datePicker"
                v-model="currentDate"
                class="date-picker"
                type="date"
                placeholder="选择日期"
                format="yyyy-MM-dd HH:mm:ss"
                :picker-options="timePickerOptions"
                @change="handleCurrentDateChange"
              />
            </div>
          </div>
        </div>

        <div class="header__right">
          <div class="header__right__logo">
            <img
              :src="defaultCompany.logo"
            >
          </div>

        </div>
      </div>

      <div
        v-if="list.length > 0"
        class="reserve-content"
      >
        <div
          class="reserve-content__left"
          :style="{
            'background-image': `url(${getStatus?.status?.bgImage})`
          }"
        >
          <TitleCard
            :status="getStatus?.status"
            :room-name="roomInfo?.name"
            :room-list="meetingRoomList"
            @roomChange="handleRoomChange"
          />

          <div class="meeting-info">
            <div
              v-if="getStatus?.status?.status !== 'pending'"
              class="meeting-info__data"
            >
              <div class="meeting-info__data__val title line-clamp-2">
                {{ getStatus?.current?.reason }}
              </div>
              <div>
                会议时间：{{ getTimeText(getStatus?.current?.start_time, getStatus?.current?.end_time) }}
              </div>
              <div>
                预约人：{{ getStatus?.current?.user?.username }}
              </div>

              <div class="line-clamp-2">
                会议内容：{{ getStatus?.current?.content }}
              </div>
            </div>

            <div
              :class="{
                'meeting-info__center': getStatus?.status?.status === 'pending'
              }"
            >
              <div class="qrcode">
                <div
                  v-loading="qrcodeLoading"
                  class="qrcode__img"
                  @click="getReserveQrcode"
                >
                  <img
                    :src="qrcodePath"
                  >
                </div>

                <div class="qrcode__text">扫码预约</div>
              </div>
            </div>
          </div>
        </div>

        <div
          class="reserve-content__right"
          @mouseenter="stopAutoCarouselChange"
          @mouseleave="startAutoCarouselChange"
        >
          <div class="carousel-arrow">
            <div @click="handleChangeCarousel('pre')">
              <i class="el-icon-arrow-left" />
            </div>
            <div @click="handleChangeCarousel('next')">
              <i class="el-icon-arrow-right" />
            </div>
          </div>

          <template v-if="getStatus.status.status !== 'comingSoon'">
            <div class="reserve-content__right__title">
              <span>{{ isNotToday ? '该日' : '今日' }}剩余会议</span><span>（{{ list.length }}）</span>
            </div>

            <div class="reserve-content__right__list">
              <div
                v-for="(meeting, mIndex) in meetingListFormat?.[currentCarousel]"
                :key="mIndex"
                class="flex list-item"
              >
                <div class="left">
                  <SvgIcon icon-class="meeting" class-name="icon" />
                </div>

                <div class="right info">
                  <div class="info__title line-clamp-2">
                    {{ meeting?.reason }}
                  </div>
                  <div class="flex info__content">
                    <div>
                      {{ getTimeText(meeting?.start_time, meeting?.end_time) }}
                    </div>
                    <div
                      class="line-clamp-1"
                      style="width: 80%;"
                    >
                      {{ meeting?.user?.username }}
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </template>

          <template v-else>
            <div class="reserve-content__right__title">
              <span>参会人员</span><span>（{{ getStatus?.current?.users?.length }}）</span>
            </div>

            <div class="reserve-content__meeting-user">
              <div
                v-for="(user, index) in getMeetingUsers"
                :key="index"
                class="reserve-content__meeting-user__item"
              >
                <div class="icon-warp">
                  <SvgIcon
                    :icon-class="user.gender === 1 ? 'male' : 'female'"
                    class-name="avatar"
                  />
                </div>
                <div class="name-text line-clamp-1">
                  {{ user.username }}
                </div>
              </div>
            </div>
          </template>
        </div>
      </div>

      <div
        v-else
        class="reserve-empty"
      >
        <div>
          <el-dropdown
            trigger="click"
            @command="handleRoomChange"
          >
            <div class="reserve-empty__name">
              {{ roomInfo?.name }}<i class="el-icon-caret-bottom" />
            </div>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item
                  v-for="(item, index) in meetingRoomList"
                  :key="index"
                  :command="item"
                >
                  {{ item.name }}
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
        <div class="reserve-empty__tips">
          空闲中，今日无预约会议
        </div>

        <div class="qrcode reserve-empty__qrcode">
          <div
            v-loading="qrcodeLoading"
            class="qrcode__img"
            @click="getReserveQrcode"
          >
            <img
              :src="qrcodePath"
            >
          </div>

          <div class="qrcode__text">扫码预约</div>
        </div>
      </div>
    </div>

    <!--    <div class="mask" />-->
  </div>
</template>
<script>
import dayjs from 'dayjs'
import { mapGetters } from 'vuex'
import TitleCard from '@/views/conferenceRoomAppointment/components/weeklyView/TitleCard.vue'
import SvgIcon from '@/components/SvgIcon/index.vue'
import { getConferenceRoomList, getReserveQrCode, getReserveRecords } from '@/api/conferenceRoom'
import { WebSocketClient } from '@/utils/webSocket'
import { bind } from '@/api/v2/visitor'

const week = [
  '周日',
  '周一',
  '周二',
  '周三',
  '周四',
  '周五',
  '周六'
]
const CHUNK_SIZE = 3

const PAGE_SIZE = 9
export default {
  name: '',
  components: {
    TitleCard,
    SvgIcon
  },
  data() {
    return {
      list: [],
      timeInfo: {
        time: dayjs().format('HH:mm')
        // ymd: dayjs().format('YYYY/MM/DD'),
        // day: week[dayjs().day()]
      },
      roomInfo: null,
      params: {
        state: 'success',
        time: []
      },
      loading: false,
      timer: null,
      carouselTimer: null,
      currentCarousel: 0,
      page: 1,
      socketClient: null,
      refreshTimer: null,
      qrcodeLoading: false,
      qrcodePath: '',
      meetingRoomList: [],
      currentDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
      timePickerOptions: {
        disabledDate: (time) => {
          return time.getTime() < Date.now() - 86400000
        }
      }
    }
  },
  computed: {
    ...mapGetters(['defaultCompany']),

    stateMap() {
      return {
        inProgress: {
          bgImage: 'https://obs-user-test.obs.cn-east-3.myhuaweicloud.com:443/pictures/test_1749797462_lPAiE42KKh.png',
          color: '#DA291C',
          status: 'inProgress',
          text: '会议进行中'
        },

        comingSoon: {
          bgImage: 'https://obs-user-test.obs.cn-east-3.myhuaweicloud.com:443/pictures/test_1749797682_UdVpSMVIwv.png',
          color: '#FFB101',
          status: 'comingSoon',
          text: '会议即将开始'
        },

        pending: {
          bgImage: 'https://obs-user-test.obs.cn-east-3.myhuaweicloud.com:443/pictures/test_1749797682_UdVpSMVIwv.png',
          color: '#2B8CF1',
          status: 'pending',
          text: '当前暂无会议'
        }
      }
    },

    backgroundImage() {
      const bg = {
        noAppointment: 'https://obs-user-test.obs.cn-east-3.myhuaweicloud.com:443/pictures/test_1749797894_NkJ9GPEz2X.png',
        appointment: 'https://obs-user-test.obs.cn-east-3.myhuaweicloud.com:443/pictures/test_1749798042_pLtx2mOvTx.png'
      }

      return this.list.length ? bg.appointment : bg.noAppointment
    },

    meetingListFormat() {
      const list = this.list
      const sortList = list.sort((a, b) => {
        return dayjs(a.start_time).isBefore(dayjs(b.start_time)) ? -1 : 1
      })
      const grouped = []

      for (let i = 0; i < sortList.length; i += CHUNK_SIZE) {
        grouped.push(sortList.slice(i, i + CHUNK_SIZE))
      }

      return grouped
    },

    getStatus() {
      const now = dayjs()
      const oneHourLater = now.add(0.5, 'hour')
      const list = this.list

      const matches = list.filter(item => {
        const start = dayjs(item.start_time)
        const end = dayjs(item.end_time)
        return start.isBefore(oneHourLater) && end.isAfter(now)
      })

      if (matches.length) {
        // 近半小时内有预约数据
        const current = this.meetingListFormat[0][0]
        const startTime = dayjs(current.start_time)
        const endTime = dayjs(current.end_time)
        if (startTime.isBefore(now) && endTime.isAfter(now)) {
          /**
           * 列表第一个的开始时间在当前时间之前，
           * 并且结束时间在当前时间之后的为正在进行中
           * 状态为inProgress
           */
          return {
            status: this.stateMap['inProgress'],
            current
          }
        } else {
          // 列表第一个的开始时间在当前时间之后，状态为comingSoon
          return {
            status: this.stateMap['comingSoon'],
            current
          }
        }
      } else {
        // 近半小时内无预约数据， 状态为pending
        return {
          status: this.stateMap['pending'],
          current: null
        }
      }
    },

    getMeetingUsers() {
      const users = this.getStatus.current?.users
      const start = (this.page - 1) * PAGE_SIZE
      return users.slice(start, Math.min(start + PAGE_SIZE, users.length))
    },

    getTimeInfo() {
      const time = dayjs(this.currentDate)
      const ymd = time.format('YYYY/MM/DD')
      const day = time.day()
      return {
        ymd,
        day: week[day]
      }
    },

    isNotToday() {
      return dayjs().format('YYYY-MM-DD') !==
        dayjs(this.currentDate).format('YYYY-MM-DD')
    }
  },

  created() {
    this.connectWebSocket()
    this.init()
    this.updateFun()
    this.doRefresh()
  },

  beforeDestroy() {
    clearInterval(this.timer)
    clearInterval(this.carouselTimer)
    clearInterval(this.refreshTimer)
  },

  methods: {
    connectWebSocket() {
      this.socketClient = new WebSocketClient(process.env.VUE_APP_WS_URL)

      this.socketClient.connect()

      this.socketClient.onMessage = this.onMessage
    },

    async onMessage(data) {
      switch (data.type) {
        case 'sendMessage':
          break

        case 'bind':
          await this.bindClient('bind', data.data)
          break

        case 'refresh':
          await this.getList()
          break
      }
    },

    async bindClient(type, data) {
      await bind({ type, client_id: data }).catch((e) => {
        throw new Error(e?.response?.data?.message ?? '绑定失败')
      })
    },

    async init() {
      await this.getRoomList()
      const route = this.$route
      if (route.query.id && route.query.name) {
        this.roomInfo = {
          id: route.query.id,
          name: route.query.name
        }
      } else {
        const room = this.meetingRoomList?.[0]
        console.log('room --------->', room)
        this.roomInfo = {
          id: room?.id,
          name: room?.name
        }
      }

      const start = dayjs(this.currentDate).startOf('day').format('YYYY-MM-DD HH:mm:ss')
      const end = dayjs(this.currentDate).endOf('day').format('YYYY-MM-DD HH:mm:ss')

      this.params.time = [start, end]

      await this.getList()

      await this.getReserveQrcode()

      this.startAutoCarouselChange()
    },

    async getRoomList() {
      try {
        const res = await getConferenceRoomList()
        this.meetingRoomList = res.data
      } catch (error) {
        throw new Error(error?.response?.data?.message || '会议室列表获取失败')
      }
    },

    updateFun() {
      this.timer = setInterval(() => {
        this.getNowTime()
        this.updateMeetingList()
      }, 1000)
    },

    async getList() {
      this.loading = true
      try {
        const res = await getReserveRecords({
          ...this.params,
          time: this.params.time && this.params.time.length
            ? JSON.stringify(this.params.time) : null,
          id: this.roomInfo?.id
        })
        this.list = res.data.map(item => {
          const roomInfo = JSON.parse(item.room)
          return {
            ...item,
            room_name: roomInfo.name,
            room: roomInfo
          }
        })
        this.updateMeetingList()
      } catch (error) {
        console.log('error --------->', error)
        this.$message.error('获取预约记录失败')
      } finally {
        this.loading = false
      }
    },

    updateMeetingList() {
      this.list = this.list.filter(item => {
        return dayjs(item.end_time).isAfter(dayjs())
      })
    },

    getNowTime() {
      const now = dayjs()
      // const ymd = now.format('YYYY/MM/DD')
      // const day = now.day()

      const time = now.format('HH:mm')

      this.timeInfo = {
        // ymd,
        // day: week[day],
        time
      }
    },

    getTimeText(start, end) {
      const startTime = dayjs(start).format('HH:mm')
      const endTime = dayjs(end).format('HH:mm')

      return `${startTime}~${endTime}`
    },

    startAutoCarouselChange() {
      this.timer = null

      this.carouselTimer = setInterval(() => {
        this.handleChangeCarousel('next')
      }, 5000)
    },

    stopAutoCarouselChange() {
      clearInterval(this.carouselTimer)
    },

    handleChangeCarousel(type) {
      if (this.getStatus.status.status === 'comingSoon') {
        this.meetingUserPageChange()
      } else {
        this.meetingListPageChange(type)
      }
    },

    meetingListPageChange(type) {
      const len = this.meetingListFormat?.length
      if (type === 'prev') {
        this.currentCarousel = this.currentCarousel === 0
          ? len - 1
          : this.currentCarousel - 1
      } else {
        this.currentCarousel = this.currentCarousel >= len - 1
          ? 0
          : this.currentCarousel + 1
      }
    },

    meetingUserPageChange(type) {
      const usersLen = this.getStatus.current?.users?.length
      const maxPage = Math.ceil(usersLen / PAGE_SIZE)

      if (type === 'prev') {
        this.page = this.page <= 1 ? maxPage : this.page - 1
      } else {
        this.page = this.page >= maxPage ? 1 : this.page + 1
      }
    },

    doRefresh() {
      this.refreshTimer = setInterval(() => {
        this.getList()
      }, 30 * 60 * 1000)
    },

    async getReserveQrcode() {
      this.qrcodeLoading = true
      try {
        const res = await getReserveQrCode({ roomId: this.roomInfo.id })
        this.qrcodePath = res.data
      } catch (error) {
        this.$message.error('二维码获取失败')
      } finally {
        this.qrcodeLoading = false
      }
    },

    handleOpenDatePicker() {
      this.$refs.datePicker.focus()
    },

    handleCurrentDateChange() {
      const start = dayjs(this.currentDate).startOf('day').format('YYYY-MM-DD HH:mm:ss')
      const end = dayjs(this.currentDate).endOf('day').format('YYYY-MM-DD HH:mm:ss')

      this.params.time = [start, end]

      this.getList()
    },

    handleRoomChange(e) {
      console.log('e --------->', e)
      const { id, name } = e
      if (this.roomInfo.id / 1 === id) {
        return
      }
      this.roomInfo = {
        id,
        name
      }
      this.getList()
      this.getReserveQrcode()
    }
  }
}
</script>
<style lang="scss" scoped>
.weekly-view {
  position: relative;
  padding: 48px;
  height: 100%;
  background-color: #F5F5F5;
  background-repeat: no-repeat;
  background-size: cover;
  overflow-y: auto;

  &__content {
    position: relative;
    z-index: 99;

    .qrcode {
      &__img {
        width: 180px;
        height: 180px;

        img {
          width: 100%;
          height: 100%;
        }
      }

      &__text {
        margin-top: 16px;
        font-size: 36px;
        text-align: center;
      }
    }

    .header {
      display: flex;
      justify-content: space-between;
      align-items: center;

      &__left {
        .header__left__time {
          color: #000000;

          .time {
            font-size: 72px;
            font-weight: bold;
          }

          .date {
            position: relative;
            font-size: 36px;
            font-weight: 500;

            > div {
              &:nth-child(2) {
                margin-left: 24px;
              }
            }

            .date-picker {
              position: absolute;
              top: 0;
              left: 0;
              opacity: 0;
              //visibility: hidden;
              //width: 1px;
            }
          }
        }
      }

      &__right {
        &__logo {

          img {
            max-width: 300px;
            height: 110px;
            object-fit: scale-down;
          }
        }
      }

    }

    .reserve-content {
      margin-top: 48px;
      display: flex;

      &__left {
        width: 60%;
        margin-right: 48px;
        padding: 72px 80px;
        background-size: 100% 100%;
        background-repeat: no-repeat;
        border-radius: 32px;

        .meeting-info {
          margin-top: 62px;
          display: flex;
          align-items: center;

          &__center {
            width: 100%;
            display: flex;
            justify-content: center;
          }

          &__data {
            width: 80%;
            color: #000000;
            font-weight: 500;
            font-size: 40px;
            margin-right: 40px;

            .title {
              font-size: 54px;
            }

            > div {
              margin-bottom: 32px;
              &:last-child {
                margin-bottom: 0;
              }
            }
          }
        }

      }

      &__right {
        position: relative;
        width: 40%;
        background: rgba(255,255,255,0.5);
        border-radius: 32px;
        border: 3px solid #FFFFFF;
        padding: 54px 72px;

        .carousel-arrow {
          padding: 0 20px;
          position: absolute;
          width: 100%;
          top: 50%;
          left: 0;
          transform: translateY(-50%);
          display: flex;
          justify-content: space-between;

          >div {
            cursor: pointer;
            width: 36px;
            height: 36px;
            border-radius: 50%;
            background-color: rgba(0, 0, 0, .1);
            color: #FFF;
            display: flex;
            justify-content: center;
            align-items: center;
            transition: all .3s;
            &:hover {
              background-color: rgba(0, 0, 0, .2);
            }
          }

        }

        &__title {
          color: #000000;
          padding-bottom: 32px;
          border-bottom: 1px solid #B3D8F4;
          > span {
            font-weight: 700;

            &:first-child {
              font-size: 72px;
            }

            &:last-child {
              font-size: 36px;
            }
          }
        }

        &__list {
          width: 100%;
          margin-top: 36px;
          //display: flex;
          overflow: hidden;

          .carousel {
            width: 100%;
            flex: 0 0 auto;
          }

          .list-item {
            margin-bottom: 48px;

            &:last-child {
              margin-bottom: 0;
            }

            .left {
              margin-right: 16px;
              margin-top: 12px;

              .icon {
                width: 40px;
                height: 40px;
              }
            }

            .info {
              flex: 1;
              &__title {
                font-size: 40px;
                line-height: 54px;
              }

              &__content {
                margin-top: 8px;
                font-size: 36px;
                line-height: 52px;
                > div {
                  &:last-child {
                    margin-left: 48px;
                  }
                }
              }
            }
          }
        }

      }

      &__meeting-user {
        margin-top: 36px;
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        grid-template-rows: repeat(3, 146px);
        gap: 48px;

        &__item {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;

          .name-text {
            margin-top: 4px;
            font-size: 32px;
            color: #333333;
          }
        }

        .icon-warp {
          .avatar {
            width: 96px;
            height: 96px;
          }
        }
      }

    }

    .reserve-empty {
      width: 100%;
      padding: 84px 0;
      text-align: center;

      &__name {
        color: #000000;
        font-weight: 700;
        font-size: 96px;
      }

      &__tips {
        margin: 48px 0;
        font-weight: 700;
        font-size: 120px;
        color: #2B8CF1;
      }

      &__qrcode {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
      }

    }
  }

  .mask {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    opacity: .3;
    background: linear-gradient(230deg, rgba(93,195,250,0.3) 0%, rgba(93,195,250,0) 74%), #D8D8D8;

  }
}
</style>
